home *** CD-ROM | disk | FTP | other *** search
- /* Spearmans Rho Test */
-
- options results
- if ~show('P','TCALC') then do
- address command 'run turbocalc:turbocalc'
- address command 'waitforport TCALC'
- loadflag=1
- end
- address 'TCALC'
- 'DEFPUBSCREEN()'
- /* Add-in Rexx Math Library needed for some routines */
- signal on syntax
- if ~show('l','rexxmathlib.library') then
- call addlib('rexxmathlib.library',0,-30)
- if ~show('l','rexxreqtools.library') then
- call addlib('rexxreqtools.library',0,-30)
- if ~show('l','rexxsupport.library') then
- call addlib('rexxsupport.library',0,-30)
- /* add to library list */
- signal off syntax
-
- /* Start Main Routine */
- if loadflag=1 then 'Load()'
- 'ActivateWindow()'
- range=rtgetstring(,"Enter Cell Range for Input","Input Request") /*,,'rt_pubscrname="TCALC"')*/
- colon=pos(":",range)
- if colon=0 then do
- 'Message "Please select a range before executing this script"'
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
-
- /* Find cell references and cell, column numbers */
- start_cell=substr(range,1,colon-1)
- end_cell=substr(range,colon+1)
- start_row=cellrow(start_cell)
- end_row=cellrow(end_cell)
- start_col=cellcol(start_cell)
- end_col=cellcol(end_cell)
- NRows=end_row-start_row+1
- NCols=end_col-start_col+1
- if NCols>2 then do
- 'Message "Only two columns allowed!"'
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
-
- /* Get cell reference for output range */
- out_cell=rtgetstring(,"Enter Cell Reference for Output","Input Request") /*,,'rt_pubscrname="TCALC"')*/
- if out_cell="" then do
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
- if length(out_cell)<2 | datatype(left(out_cell,1),'n') then do
- 'Message "Invalid cell reference"'
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
- /* Suppress Screen Redraw to Speed Things Up */
- 'Refresh 0'
-
- /* Open a small output window on tcalc screen*/
- fo=0
- CR='0a'x
- DisplayMsg="Calculating...Please Wait."||CR||"User input is disabled during calculation."||CR
- if open(6Info, 'con:100/0/450/80/Progress/SCREEN TCALC', w) then do
- call writeln(6Info, DisplayMsg)
- fo=1
- end
- else do
- 'Message "TCALC Screen not available for Progress messages"'
- end
- CALL DELAY(150)
-
- /* Get cell references for top cell in each column */
- 'SelectCell' start_cell
- do col=start_col to end_col
- 'GetCursorPos'
- top_cell.col=result
- 'Column 1'
- end
-
- /* Get labels for later use on output */
- 'SelectCell' start_cell
- 'GetValue'
- testlabel=result
- testlabel=strip(testlabel)
- if datatype(testlabel,'n')=1 then do
- labelflag=0
- do x=1 to NCols
- title.x="Column "||x
- end
- end
- else do
- labelflag=1
- NRows=NRows-1
- do x=1 to NCols
- 'GetValue'
- str=result
- title.x=translate(strip(str),"_"," ")
- 'Column 1'
- end
- end
- if fo then call writech(6Info,"Progress...10 ")
-
- /* Get data from cell range */
- col=start_col
- lav=0
- tot=0
- count.=0
- total.=0
- temp.=0
- do x=1 to NCols
- 'SelectCell' top_cell.col
- if labelflag=1 then 'CursorDown 1'
- do y=1 to NRows
- 'GetValue'
- valtest=result
- if datatype(valtest)='NUM' then do
- 'GetValue'
- val=result
- data.x.y=val
- temp.x.y=val
- count.x=1+count.x
- end
- 'CursorDown 1'
- end
- col=col+1
- val=0
- end
- if fo then call writech(6Info,"20 ")
-
- /* Sort Temp Values */
- call Sort()
- if fo then call writech(6Info,"40 ")
-
-
- /* Calculate Ranks for Temp array */
-
- Rank.=0
- NTies=0
- Do x=1 to NCols
- N=count.x
- Do y=1 to NRows
- z=y+1
- if temp.x.y=temp.x.z then do
- cnt=1
- beginrank=y
- avrank=y
- endrank=0
- do until endrank~=0
- y=y+1
- avrank=avrank+y
- z=y+1
- cnt=cnt+1
- if temp.x.y~=temp.x.z then endrank=y
- end
- if cnt>1 then NTies=NTies+1
- avrank=(avrank/cnt)
- do y=beginrank to endrank
- Rank.x.y=trunc(avrank,2)
- end
- y=y-1
- end
- else do
- Rank.x.y=y
- end
- end
- end
- if fo then call writech(6Info,"60 ")
-
- /*Compare data to temp ranks and get data ranks */
- Rk.=0
- DO x=1 to NCols
- Do y=1 to NRows
- j=1
- Do j=1 to NRows
- if data.x.y=temp.x.j then do
- Rk.x.y=Rank.x.j
- leave j
- end
- end
- end
- end
- if fo then call writech(6Info,"80 ")
-
- /* Calculate Rho */
- TR=0
- SR=0
- SX=0
- SY=0
- SQ=0
- TT=0
- SD1=0
- SD2=0
- ZM=(NRows*((NRows+1)/2)**2)
- /* DO y=1 to NRows
- SX=(Rk.1.y)-((NRows+1)/2)
- SY=(Rk.2.y)-((NRows+1)/2)
- SQ=SQ+SX*SY
- end
- Rhoa=SQ/((NRows*((NRows**2)-1))/12)
- */
- if NTies~=0 then DO
- in=2
- de=1
- Do x=1 to NCols
- Do y=1 to NRows
- total.x=(total.x)+Rk.x.y
- end
- end
- /* Calculate Means */
- mean.=0
- do x=1 to NCols
- mean.x=(total.x)/NRows
- end
- say mean.1
- say mean.2
- /* Calculate diffs */
- diff.=0
- sum.=0
- dat=0
- meenx=0
- Do x=1 to NCols
- meenx=mean.x
- Do y= 1 to NRows
- dat=Rk.x.y
- diff.x.y=dat-meenx
- sum.x=(dat-meenx)**2+(sum.x)
- end
- say sum.x
- end
- diffMult.=0
- summulti=0
- Do y=1 to NRows
- diffMult.y=(diff.de.y)*(diff.in.y)
- summulti=summulti+(diffMult.y)
- end
- rs=0
- pr=0
- rs=((summulti)**2)/((sum.in)*(sum.de))
- Rhob=sqrt(rs)
- end
- DO y=1 to NRows
- TR=TR+((Rk.1.y)-Rk.2.y)**2
- end
- Rhoa=1-(6*TR)/(NRows*((NRows**2)-1))
-
-
- /* calculate Rho Probability */
- r=0
- ProbRho=0
- IF NTies=0 then do
- ProbRho=1-PRHO(NRows,Rhoa)
- if Rhoa~=1 then t=(Rhoa*sqrt(NRows-2))/(sqrt(1-Rhoa**2))
- end
- Else do
- ProbRho=1-PRHO(NRows,Rhob)
- if Rhob~=1 then t=(Rhob*sqrt(NRows-2))/(sqrt(1-Rhob**2))
- end
- df=NRows-2
- If Rhoa~=1 & Rhoab~=1 then do
- /* Calculate T distribution function */
-
- P=PROBT(t,df)
- if t>=0 then P=1-P
- PT=P*2
- /* Calculate T Critical */
-
- TCRIT1=TCRITICAL(.95,df)
- TCRIT2=TCRITICAL(.99,df)
- TCRIT3=TCRITICAL(.975,df)
- if fo then call writech(6Info,"90 ")
- TCRIT4=TCRITICAL(.995,df)
- end
- if fo then do
- call writeln(6Info,"100")
- call writeln(6Info,"Writing output to window...")
- end
-
- /* Output */
- 'SelectCell' out_cell
- 'ColumnWidth 17'
- 'Put "Spearmans Rho - Rank Correlation Non-Parametric Test"'
- 'CursorDown 1'
- Do x=1 to NCols
- title="Rank_"||title.x
- 'Alignment 2'
- 'Put' title
- 'CursorDown 1'
- Do y=1 to NRows
- 'Put' Rk.x.y
- 'CursorDown 1'
- end
- 'CursorUp' NRows+1
- 'Column 1'
- end
- 'SelectCell' out_cell
- 'CursorDown' NRows+3
- 'Put "Ties:"'
- 'Column 1'
- 'Put' NTies
- 'Column -1'
- 'CursorDown 1'
- 'Put "Rho (no Ties):"'
- 'Column 1'
- 'Put' format(Rhoa,,4)
- If NTies~=0 then do
- 'CursorDown 1'
- 'Put' format(Rhob,,4)
- 'Column -1'
- 'Put "Rho (corrected for ties):"'
- 'Column 1'
- end
- 'CursorDown 1'
- 'Put' format(ProbRho,,6)
- 'Column -1'
- 'Put "Prob.(Rho<=rho):"'
- If Rhoa~=1 & Rhoab~=1 then do
- 'CursorDown 1'
- 'GetCursorPos'
- new_cell=result
- 'Put "d.f.:"'
- 'CursorDown 1'
- 'Put "t:"'
- 'CursorDown 1'
- 'Put "P(T<=t) one-tail:"'
- 'CursorDown 1'
- 'Put "T-Critical (95%):"'
- 'CursorDown 1'
- 'Put "T-Critical (99%):"'
- 'CursorDown 1'
- 'Put "P(T<=t) two-tail:"'
- 'CursorDown 1'
- 'Put "T-Critical (95%):"'
- 'CursorDown 1'
- 'Put "T-Critical (99%):"'
- 'SelectCell' new_cell
- 'Column 1'
- 'Put' df
- 'CursorDown 1'
- 'Put' format(t,,4)
- 'CursorDown 1'
- 'Put' format(P,,6)
- 'CursorDown 1'
- 'Put' format(TCRIT1,,4)
- 'CursorDown 1'
- 'Put' format(TCRIT2,,4)
- 'CursorDown 1'
- 'Put' format(PT,,6)
- 'CursorDown 1'
- 'Put' format(TCRIT3,,4)
- 'CursorDown 1'
- 'Put' format(TCRIT4,,4)
- end
- 'Refresh 1'
- 'Refresh 2'
- /*'Message' "Finished"*/
- /*indicate the main script is finished*/
- DisplayMsg="Cleaning up ...."||CR||"Exiting"
- result=writeln(6Info, DisplayMsg)
- if result~=0 then do
- /*Wait 3 seconds*/
- CALL DELAY(150)
- /* close window*/
- result=close(6Info)
- end
- 'DEFPUBSCREEN("Workbench")'
- exit
-
- /* Procedures */
-
- cellrow: procedure
- do
- parse arg cell
- do charpos=2 to length(cell)
- if datatype(substr(cell,charpos,1),n) then return substr(cell,charpos)
- end
- return 0
- end
- Return
-
- cellcol: procedure
- do
- parse arg cell
- labels="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- cell=upper(cell)
- len=length(cell)
- val=0
- do charpos=1 to len
- if datatype(substr(cell,charpos,1),n) then
- do cell=reverse(substr(cell,1,charpos-1))
- do x=1 to length(cell)
- val=(26**(x-1))*pos(substr(cell,x,1),labels)+val
- end
- return val
- end
- end
- return 0
- end
- Return
-
- /* It is important to put the exposed array at the end of the next line */
- Sort: procedure expose NCols NRows temp.
- do x=1 to NCols
- L=(xtoy(2,int(log(NRows)/log(2))))-1
- Do Until L<1
- L=trunc(int(L/2))
- Do J=1 to L
- Do K=J+L To NRows By L
- I=K
- dumdat=temp.x.I
- Do while I>L
- y=I-L
- If temp.x.y ~> dumdat then Leave
- temp.x.I=temp.x.y
- I=I-L
- End
- temp.x.I=dumdat
- End
- End
- End
- End
- Return
-
- syntax:
- if arg(1)='FAIL' then do
- 'Message "Library is unavailable."'
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
- 'DEFPUBSCREEN("Workbench")'
- exit
-
- Format: procedure
-
- arg number, before, after
- CallLine = SIGL
- if ~datatype(CallLine, 'N') then CallLine = '??'
-
- /* Make sure we have a number as first (required) argument */
- if ~datatype(number, 'N') then do
- if number = '' then
- fc = 17 /* Wrong number of arguments */
- else
- fc = 47 /* Arithmetic conversion error */
- signal FormatSyntaxError
- end
- num = number + 0
- if before = '' & after = '' then
- return num
- else do
- parse var num integer '.' fraction
- if before = '' then before = length(integer)
- if after = '' then after = length(fraction)
- if ~datatype(before, N) | ~datatype(after, N) then
- do fc = 18
- signal FormatSyntaxError
- end
- if before < length(integer) then do
- fc = 18
- signal FormatSyntaxError
- end
- if after ~= length(fraction) then do
- fraction = trunc(('.'fraction'0') + ('.'copies('0', after)'5'), after)
- if integer<1&integer>-1 then integer=integer
- else integer = integer + (fraction % 1)
- fraction = substr(fraction, 3)
- end
- if fraction >= 0 then
- return right(integer, before)'.'fraction
- else
- return right(integer, before)
- end
-
- FormatSyntaxError:
- if show('F', STDERR) then
- call writeln(STDERR, '+++ Error' fc 'in line' CallLine':' errortext(fc))
- else
- mess='+++ Error' fc 'in line' CallLine':' errortext(fc)
- 'Message' mess
- parse source Func .
- if Func = 'FUNCTION' then do
- 'DEFPUBSCREEN("Workbench")'
- exit "Err"
- end
- else do
- 'DEFPUBSCREEN("Workbench")'
- exit 10
- end
-
- /* Algorithm AS 89 Appl. Statist. (1975) Vol.24, No. 3, P377.
- c
- c To evaluate the probability of obtaining a value greater than or
- c equal to is, where is=(n**3-n)*(1-r)/6, r=Spearman's rho and n
- c must be greater than 1
- c
- c Auxiliary function required: ALNORM = algorithm AS66
- */
-
- PRHO: Procedure
-
- parse arg n, r
- is=(n**3-n)*(1-r)/6
- l.=0
- zero=0
- one=1
- two=2
- six=6
- c1=0.2274
- c2=0.2531
- c3=0.1745
- c4=0.0758
- c5=0.1033
- c6=0.3932
- c7=0.0879
- c8=0.0151
- c9=0.0072
- c10=0.0831
- c11=0.0131
- c12=0.00046
- /*Test admissibility of arguments and initialize*/
- prho = one
- if (n <= 1) then return 0
- if (is <= 0) then return 0
- prho = zero
- if (is > n * (n * n -1) / 3) then return 0
- js = is
- if (js ~= 2 * (js / 2)) then js = js + 1
- if (n <= 6) then DO
- /* Exact evaluation of probability*/
- nfac = 1
- do i = 1 to n
- nfac = nfac * i
- l.i = i
- end
- prho = one / nfac
- if (js ~= n * (n * n -1) / 3) then return
- ifr = 0
- do m = 1 to nfac
- ise = 0
- do i = 1 to n
- ise = ise + (i - l.i) ** 2
- end
- if (js <= ise) then ifr = ifr + 1
- n1 = n
- DO UNTIL m=nfac
- mt = l.1
- nn = n1 - 1
- do i = 1 to nn
- j=i+1
- l.i = l.j
- end
- l.n1 = mt
- if (l.n1 ~= n1 | n1 = 2) then leave m
- n1 = n1 - 1
- end
- end
- prho = ifr / nfac
- return prho
- end
- Else Do
- b = one / n
- x = (six * (js - one) * b / (one / (b * b) -one) -one) * sqrt(one / b - one)
- y = x * x
- u = x * b * (c1 + b * (c2 + c3 * b) + y * (-c4+ b * (c5 + c6 * b) - y * b * (c7 + c8 * b- y * (c9 - c10 * b + y * b * (c11 - c12 * y)))))
- prho = u / exp(y / two) + znorm(x,1)
- if (prho < zero) then prho = zero
- if (prho > one) then prho = one
- end
- return prho
-
- /*Algorithm AS66 Applied Statistics (1973) vol22 no.3*/
-
- /*Evaluates the tail area of the standardised normal curve
- from x to infinity if upper is .true. or
- from minus infinity to x if upper is .false.*/
-
- znorm: procedure
- parse arg x, upper
- zero=0
- one=1
- half=.5
- ltone=7.0
- utzero=18.66
- con=1.28
- p=0.398942280444
- q=0.39990348504
- r=0.398942280385
- a1=5.75885480458
- a2=2.62433121679
- a3=5.92885724438
- b1=-29.8213557807
- b2=48.6959930692
- c1=-3.8052e-8
- c2=3.98064794e-4
- c3=-0.151679116635
- c4=4.8385912808
- c5=0.742380924027
- c6=3.99019417011
- d1=1.00000615302
- d2=1.98615381364
- d3=5.29330324926
- d4=-15.1508972451
- d5=30.789933034
- up=upper
- z=x
- if (z<zero) then do
- up=0
- z=-z
- end
- if (z>ltone | up=0 & z>utzero) then Do
- alnorm=zero
- if (up=0) then alnorm=one-alnorm
- return alnorm
- end
- y=half*z*z
- if (z<=con) then do
- alnorm=half-z*(p-q*y/(y+a1+b1/(y+a2+b2/(y+a3))))
- if (up=0) then alnorm=one-alnorm
- return alnorm
- end
- alnorm=r*exp(-y)/(z+c1+d1/(z+c2+d2/(z+c3+d3/(z+c4+d4/(z+c5+d5/(z+c6))))))
- if (up=0) then alnorm=one-alnorm
- return alnorm
-
- PROBT: PROCEDURE
-
- PARSE ARG TA,K1
- A=.36338023
- W=ATAN(TA/SQRT(K1))
- S=SIN(W)
- C=COS(W)
- L=K1-2*INT(K1/2)
- IF L=0 THEN DO
- T1=S
- IF K1=2 THEN DO
- PO=.5*(1+T1)
- RETURN PO
- END
- T2=S
- J1=-1
- J2=0
- K2=(K1-2)/2
- END
- ELSE DO
- T1=W
- IF K1=1 THEN DO
- T1=T1*(1-A*L)
- PO=.5*(1+T1)
- RETURN PO
- END
- T2=S*C
- T1=T1+T2
- IF K1=3 THEN DO
- T1=T1*(1-A*L)
- PO=.5*(1+T1)
- RETURN PO
- END
- J1=0
- J2=1
- K2=(K1-3)/2
- END
- DO I=1 TO K2
- J1=J1+2
- J2=J2+2
- T2=T2*C*C*J1/J2
- T1=T1+T2
- END
- T1=T1*(1-A*L)
- PO=.5*(1+T1)
- RETURN PO
-
- TCRITICAL: PROCEDURE
-
- PARSE ARG PO,K1
- AO=.0001
- E=.005
- E2=E+E
- A=2*PO-1
- IF K1=1 THEN DO
- TO=TAN(1.57079633*A)
- RETURN TO
- END
- IF K1=2 THEN DO
- SN=SIGN(2/(1-A*A))
- IF SN=-1 THEN TO=-1*(A*SQRT(ABS(2/(1-A*A))))
- ELSE TO=A*SQRT(2/(1-A*A))
- RETURN TO
- END
- P1=PO
- Z=NORMALPP(PO)
- W=Z*(1+2/(1+8*K1))
- T3=K1*(EXP(W*W/K1)-1)
- SELECT
- WHEN Z<0 THEN TT=-1
- WHEN Z=0 THEN TT=0
- OTHERWISE TT=1
- END
- SN=SIGN(T3)
- IF SN=-1 THEN T3=-1*(TT*SQRT(ABS(T3)))
- ELSE T3=TT*SQRT(T3)
- /* LABELA:
- TO=T3
- PO=PROBT(TO,K1)
- F1=PO-P1
- TO=T3+E
- PO=PROBT(TO,K1)
- F2=PO
- TO=T3-E
- PO=PROBT(TO,K1)
- F2=F2-PO
- F2=F2/E2
- T4=T3-F1/F2
- IF ABS(T4-T3)>AO THEN DO
- T3=T4
- SIGNAL 'LABELA'
- END
- */
- T4=0
- DO FOREVER
- TO=T3
- PO=PROBT(TO,K1)
- F1=PO-P1
- TO=T3+E
- PO=PROBT(TO,K1)
- F2=PO
- TO=T3-E
- PO=PROBT(TO,K1)
- F2=F2-PO
- F2=F2/E2
- T4=T3-F1/F2
- IF ABS(T4-T3)>AO THEN T3=T4
- ELSE LEAVE
- END
- TO=T4
-
- RETURN TO
-
- LOGGAMMA: PROCEDURE
-
- ARG XA
- C1=76.18009173
- C2=-86.50532033
- C3=24.01409822
- C4=-1.231739516
- C5=.001208580
- C6=-.000005364
- C7=2.506628275
- X1=XA-1
- W=X1+5.5
- W=(X1+.5)*LN(W)-W
- S=1+C1/(X1+1)+C2/(X1+2)+C3/(X1+3)
- S=S+C4/(X1+4)+C5/(X1+5)+C6/(X1+6)
- L=W+LN(C7*S)
- RETURN L
-
- NORMALPP: PROCEDURE
-
- ARG P0
- A1=2.515517
- A2=.802853
- A3=.010328
- A4=1.432788
- A5=.189269
- A6=.001308
- Q=.5-ABS(P0-.5)
- SN=SIGN(-2*LN(Q))
- IF SN=-1 THEN W=-1*SQRT(ABS(-2*LN(Q))
- ELSE W=SQRT(-2*LN(Q))
- W1=A1+W*(A2+A3*W)
- W2=1+W*(A4+W*(A5+A6*W))
- ZZ=W-W1/W2
- SELECT
- WHEN (P0-.5)<0 THEN TT=-1
- WHEN (P0-.5)=0 THEN TT=0
- otherwise TT=1
- END
- ZZ=ZZ*TT
- RETURN ZZ
-